//package me.zhengjie.tcp;
//
//
//import com.digitalpetri.modbus.master.ModbusTcpMaster;
//import com.digitalpetri.modbus.master.ModbusTcpMasterConfig;
//import com.digitalpetri.modbus.requests.ReadHoldingRegistersRequest;
//import com.digitalpetri.modbus.requests.WriteSingleRegisterRequest;
//import com.digitalpetri.modbus.responses.ModbusResponse;
//import com.digitalpetri.modbus.responses.ReadHoldingRegistersResponse;
//import com.digitalpetri.modbus.responses.WriteSingleRegisterResponse;
//import io.netty.buffer.ByteBuf;
//import io.netty.util.ReferenceCountUtil;
//import lombok.RequiredArgsConstructor;
//
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.stereotype.Component;
//
//import javax.annotation.PostConstruct;
//import java.nio.charset.StandardCharsets;
//import java.util.concurrent.*;
//import java.util.concurrent.locks.ReentrantLock;
//
//@Component
//@RequiredArgsConstructor
//public class FluentFrameTCPB {
//    private static final Logger fluentFrameBLog = LoggerFactory.getLogger("fluentFrameB");
//
//    private final FluentFrameConfigB fluentFrameConfigB;
//
//    static ModbusTcpMaster master;
//
//    private final ConcurrentHashMap<Integer, ReentrantLock> addressLocks = new ConcurrentHashMap<>();
//
//    // 获取锁的方法
//    private ReentrantLock getLockForAddress(int address) {
//        return addressLocks.computeIfAbsent(address, key -> new ReentrantLock(true)); // 公平锁
//    }
//
//
//    /**
//     * 获取TCP协议的Master
//     */
//    @PostConstruct
//    public void initModbusTcpMaster() {
//        try {
//            if (master == null) {
//                // 创建配置
//                ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder(fluentFrameConfigB.getIp()).setPort(fluentFrameConfigB.getPort()).build();
//                master = new ModbusTcpMaster(config);
//                master.connect();
//            }
//        } catch (Exception e) {
//            fluentFrameBLog.error("叠合区plc连接失败，失败原因：{}", e.toString());
//        }
//    }
//
//    public Integer readHoldingRegisters(int address,int unitId) {
//        try {
//            CompletableFuture<ReadHoldingRegistersResponse> future = master
//                    .sendRequest(new ReadHoldingRegistersRequest(address, 1), unitId);
//            ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();
////            fluentFrameBLog.info("打印返回结果：{}",readHoldingRegistersResponse.toString());
//            if (readHoldingRegistersResponse != null) {
//                ByteBuf buf = readHoldingRegistersResponse.getRegisters();
//                int i = buf.readUnsignedShort();
//                ReferenceCountUtil.release(readHoldingRegistersResponse);
//                return i;
//            }
//            return null;
//        } catch (InterruptedException | ExecutionException e) {
//            fluentFrameBLog.error("读取物流区寄存器地址值时出错，错误原因：{}", e.toString());
//            return null;
//        }
//
//    }
//
//    public String readHoldingRegistersString(int address,int unitId) {
//        try {
//            CompletableFuture<ReadHoldingRegistersResponse> future = master
//                    .sendRequest(new ReadHoldingRegistersRequest(address, 10), unitId);
//            ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();
//            if (readHoldingRegistersResponse != null) {
//                ByteBuf buf = readHoldingRegistersResponse.getRegisters();
//                if (buf != null) {
//                    // 将 ByteBuf 中的内容转换为字符串
//                    String asciiString = buf.toString(StandardCharsets.US_ASCII);
//                    fluentFrameBLog.info("原始 ASCII 字符串: " + asciiString);
//
//                    // 将 ASCII 字符串转换为正确的顺序
//                    String correctedString = correctOrder(asciiString);
//                    String s = filterInvalidChars(correctedString);
//                    fluentFrameBLog.info("正确的 ASCII 字符串:{}", s);
//                    return s;
//                }
////                byte[] bytes = new byte[2];
////                buf.readBytes(bytes);
////                ReferenceCountUtil.release(readHoldingRegistersResponse);
////                return new String(bytes, StandardCharsets.UTF_8);
//            }
//            return null;
//        } catch (InterruptedException | ExecutionException e) {
//            fluentFrameBLog.error(e.getMessage());
//            return null;
//        }
//
//    }
//
//    /*public void write(int address, int value){
//        // 发送单个寄存器数据，一般是无符号16位值：比如10
//        CompletableFuture<ModbusResponse> future = master.sendRequest(new WriteSingleRegisterRequest(address, value), 0);
//    }*/
//
//    private boolean writeToRegister(int address, int value,int unitId) throws Exception {
//        try {
//            // 发送异步写入请求
//            CompletableFuture<ModbusResponse> future = master.sendRequest(new WriteSingleRegisterRequest(address, value), unitId);
//
//            // 阻塞等待结果返回，设置超时时间
//            ModbusResponse response = future.get(10000, TimeUnit.MILLISECONDS);
//
//            // 检查响应是否为写入成功的类型
//            if (response instanceof WriteSingleRegisterResponse) {
//                WriteSingleRegisterResponse writeResponse = (WriteSingleRegisterResponse) response;
//
//                // 校验返回的地址和值是否匹配
//                if (writeResponse.getAddress() == address && writeResponse.getValue() == value) {
//                    return true; // 写入成功
//                } else {
//                    fluentFrameBLog.error("写入响应内容不匹配：地址={}, 值={}, 响应={}", address, value, writeResponse);
//                }
//            } else {
//                fluentFrameBLog.error("响应类型错误，预期=WriteSingleRegisterResponse，实际={}", response.getClass().getSimpleName());
//            }
//
//            return false; // 写入失败
//        } catch (TimeoutException e) {
//            fluentFrameBLog.error("写入超时，地址={}，值={}", address, value, e);
//            return false; // 写入超时
//        } catch (Exception e) {
//            fluentFrameBLog.error("写入异常，地址={}，值={}", address, value, e);
//            throw e; // 抛出异常以便外层重试逻辑处理
//        }
//    }
//
//    public boolean writeWithRetry(int address, int value, int unitId, int maxRetries) {
//        int attempts = 0;
//        ReentrantLock lock = getLockForAddress(address); // 获取地址锁
//        boolean acquired = false;
//
//        while (attempts < maxRetries) {
//            try {
//                acquired = lock.tryLock(3000, TimeUnit.MILLISECONDS); // 尝试获取锁
//                if (acquired) {
//                    // 尝试发送写入请求并等待结果
//                    boolean success = writeToRegister(address, value,unitId);
//                    if (success) {
//                        fluentFrameBLog.info("写入成功：地址={}，值={}", address, value);
//                        return true; // 写入成功，直接退出
//                    } else {
//                        fluentFrameBLog.error("写入失败，地址={}，值={}", address, value);
//                        return false;
//                    }
//                } else {
//                    fluentFrameBLog.error("获取锁超时，第{}次重试，地址={}", attempts + 1, address);
//                }
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt(); // 恢复中断状态
//                fluentFrameBLog.error("线程中断，地址={}，值={}", address, value, e);
//                break; // 中断异常退出
//            } catch (Exception e) {
//                fluentFrameBLog.error("写入异常，第{}次重试，地址={}，值={}", attempts + 1, address, value, e);
//            } finally {
//                if (acquired) {
//                    lock.unlock(); // 确保锁释放
//                }
//            }
//            attempts++; // 增加重试计数
//        }
//        fluentFrameBLog.error("写入失败，超出最大重试次数，地址={}，值={}", address, value);
//        return false;
//    }
//    // 将 ASCII 字符串转换为正确的顺序
//    public static String correctOrder(String asciiString) {
//        StringBuilder correctedBuilder = new StringBuilder();
//        for (int i = 0; i < asciiString.length(); i += 2) {
//            // 交换每两个字节的位置
//            String high = asciiString.substring(i, i + 1);
//            String low = asciiString.substring(i + 1, i + 2);
//            correctedBuilder.append(low).append(high);
//        }
//        return correctedBuilder.toString();
//    }
//
//    // 过滤掉无效的 ASCII 字符
//    public static String filterInvalidChars(String input) {
//        StringBuilder filteredBuilder = new StringBuilder();
//        for (char c : input.toCharArray()) {
//            if (c >= 32 && c <= 126) { // 有效的 ASCII 字符范围
//                filteredBuilder.append(c);
//            }
//        }
//        return filteredBuilder.toString();
//    }
//}
